import wave

import pyaudio
import soundfile as sf
import urllib.parse, sys
import hashlib, json
from datetime import datetime
import os

# 将当前文件所在的目录添加到 sys.path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from load_infer_info import load_character, character_name, get_wav_from_text_api, models_path, update_character_info

# 从配置文件读取配置
config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "config.json")

# 存储临时文件的字典
temp_files = {}


# 用于防止重复请求
def generate_file_hash(*args):
    """生成基于输入参数的哈希值，用于唯一标识一个请求"""
    hash_object = hashlib.md5()
    for arg in args:
        hash_object.update(str(arg).encode())
    return hash_object.hexdigest()


if os.path.exists(config_path):
    with open(config_path, 'r', encoding='utf-8') as f:
        _config = json.load(f)
        tts_port = _config.get("tts_port", 5000)
        default_batch_size = _config.get("batch_size", 1)
        enable_auth = _config.get("enable_auth", "false").lower() == "true"


def tts(data):
    global character_name
    global models_path

    text = urllib.parse.unquote(data.get('text', ''))
    cha_name = data.get('cha_name', None)
    expected_path = os.path.join(models_path, cha_name) if cha_name else None

    # 检查cha_name和路径
    if cha_name and cha_name != character_name and expected_path and os.path.exists(expected_path):
        character_name = cha_name
        print(f"Loading character {character_name}")
        load_character(character_name)
    elif expected_path and not os.path.exists(expected_path):
        print({"error": f"Directory {expected_path} does not exist. Using the current character."}), 400

    text_language = data.get('text_language', '多语种混合')
    batch_size = int(data.get('batch_size', default_batch_size))
    speed_factor = float(data.get('speed', 1.0))
    top_k = int(data.get('top_k', 6))
    top_p = float(data.get('top_p', 0.8))
    temperature = float(data.get('temperature', 0.8))
    stream = data.get('stream', 'False').lower() == 'true'
    save_temp = data.get('save_temp', 'False').lower() == 'true'
    character_emotion = data.get('character_emotion', 'default')

    params = {
        "text": text,
        "text_language": text_language,
        "batch_size": batch_size,
        "speed_factor": speed_factor,
        "top_k": top_k,
        "top_p": top_p,
        "temperature": temperature,
        "character_emotion": character_emotion,
        "stream": stream
    }

    file_hash = generate_file_hash(text, text_language, top_k, top_p, temperature, character_emotion, character_name)
    if stream == False:
        if file_hash in temp_files:
            print("already exist")
        else:
            gen = get_wav_from_text_api(**params)
            sampling_rate, audio_data = next(gen)
            temp_file_path = (
                f"tmp_audio/{cha_name}{datetime.now().strftime('%Y%m%d%H%M%S')}.wav"
            )
            with open(temp_file_path, 'wb') as temp_file:
                sf.write(temp_file, audio_data, sampling_rate, format='wav')
            temp_files[file_hash] = temp_file_path
            return temp_file_path


def play_wav(file_path):
    chunk = 1024

    with wave.open(file_path, 'rb') as wav_file:
        # 打开音频文件

        audio = pyaudio.PyAudio()
        stream = audio.open(format=audio.get_format_from_width(wav_file.getsampwidth()),
                            channels=wav_file.getnchannels(),
                            rate=wav_file.getframerate(),
                            output=True)
        # 创建 PyAudio 流

        data = wav_file.readframes(chunk)
        while data:
            stream.write(data)
            data = wav_file.readframes(chunk)
        # 播放音频

        stream.stop_stream()
        stream.close()
        audio.terminate()
        # 关闭流和 PyAudio 实例